package com.lzx.hbh_system.service.user.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzx.hbh_system.bo.SysUser;
import com.lzx.hbh_system.bo.filter.UseroperaInfoFilter;
import com.lzx.hbh_system.bo.user.UserStatsInfo;
import com.lzx.hbh_system.bo.user.UseroperaInfo;
import com.lzx.hbh_system.dto.UserDto;
import com.lzx.hbh_system.mapper.SysUserMapper;
import com.lzx.hbh_system.mapper.user.UseroperaInfoMapper;
import com.lzx.hbh_system.mapper.user.UserstatsInfoMapper;
import com.lzx.hbh_system.service.user.UseroperaInfoService;
import com.lzx.hbh_system.util.*;
import com.lzx.hbh_system.util.responseEntity.RespOutMsgHeader;
import com.lzx.hbh_system.util.responseEntity.ResponseView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class UseroperaInfoServiceImpl extends ServiceImpl<UseroperaInfoMapper, UseroperaInfo> implements UseroperaInfoService {

    static final String LOGINGOUT = "/user/logout";

    @Autowired
    private UseroperaInfoMapper useroperaInfoMapper;
    @Autowired
    private UserstatsInfoMapper userstatsInfoMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Override
    public ResponseView getSomeListByFilter(UseroperaInfoFilter filter) {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        // 校验参数
        if (filter.getUserCode() == null){
            // 返回响应消息
            responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false,"请求的用户编号不能为空",500));
            return responseView;
        }
        // 逻辑实现
        List<UseroperaInfo> useroperaInfoList = useroperaInfoMapper.querySomeByFilter(filter.getUserCode());
        // 返回响应消息
        responseView.setRespOutMsgHeader(RespOutMsgHeader.success(1,true,"查询成功！"));
        // 设置返回结果
        responseView.setMain(useroperaInfoList.toArray());
        return responseView;
    }

    /**
     * 用户操作日志记录
     * @param info
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED,rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Boolean saveLogDataToUserOperainfo(UseroperaInfo info) {
        // 校验函数
        if (info == null){
            log.error("日志对象为空，日志数据保存失败！");
            return false;
        }
        String infoId = SnowFlakeUtil.getId();
        // 设置主键
        info.setOperaCode(infoId);
        // 设置唯一标识
        info.setId(infoId);
        // 保存数据-是否是用户登出情况 如果是则暂时不计入日子表中，直接进行数据统计到数据统计表中
        if(LOGINGOUT.equals(info.getRequestPath())){
            // 用户登出操作
            statstingUserData(info);
            return true;
        }
        useroperaInfoMapper.insert(info);
        return true;
    }

    /**
     * 判断用户操作日志-若是登出-则通过计算并录入到用户信息统计分析表中
     * @param info
     */
    public void statstingUserData(UseroperaInfo info){
        // 获取redis中用户登陆信息
        UserDto userDto = (UserDto) redisUtils.getObject(info.getUserName());
        if (userDto== null){
            log.error("userDto is null");
            return;
        }
        // 获取用户登入时间
        Date logInTime = TurnStringToDateUtil.setStrToTime(userDto.getLogintime());
        System.out.println("用户登入时间："+logInTime);
        Integer Days = TimetUtil.getDaysBetweenDate(logInTime,new Date(),null,"days");
        System.out.println("相差天数："+Days);
        // 先获取数据库中是否存在已经统计的当前天数在线总时长，若有则叠加总时间，若无直接添加入数据库中作为当天在线总时长
        QueryWrapper<UserStatsInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_code", userDto.getUserCode());
        wrapper.orderByDesc("create_time");
        List<UserStatsInfo> userStatsInfos = userstatsInfoMapper.selectList(wrapper);
        // 处理登陆时长逻辑
        if(userStatsInfos.size() == 0){
            log.error("当前用户尚未完善个人信息，暂时不能记录日志");
            return;
        }
        updateTime(userStatsInfos.get(0),Days,logInTime,info);
    }

    /**
     * 同步统计表数据函数
     * 1111 标识 表示需要统计同一天的数据
     * 0000 标识 表示需要统计不同一天的数据
     * // 如果是同一天则加入同一天时间 直接更新数据
     * // 如果不是同一天数据，且数据库存在则直接新增该条数据
     * @param userStatsInfo
     * @param Days
     * @param info
     */
    public void updateTime(UserStatsInfo userStatsInfo,Integer Days,Date logInTime,UseroperaInfo info){
        Integer onlineTimeAdd = TimetUtil.getDaysBetweenDate(logInTime,new Date(),null,"minutes");
        if (onlineTimeAdd <= 0){
            onlineTimeAdd = 0;
        }
        if ( userStatsInfo != null && Days == 0){ // 登陆退出时长不超过一天 ，且存在的 则叠加时长
            if ( !TurnDateToStringUtil.getTimeTo_Y_M_D(userStatsInfo.getCreateTime()).equals(TurnDateToStringUtil.getTimeTo_Y_M_D(new Date()))){
                UserStatsInfo userStatsInfonew = new UserStatsInfo();
                String Idkey = SnowFlakeUtil.getId(); // 获取主键
                userStatsInfonew.setId(Idkey); // 设置唯一标识
                userStatsInfonew.setUserstatsCode(Idkey); // 设置主键
                userStatsInfonew.setInlineTime(onlineTimeAdd ); // 设置当前用户在线实际时长
                userStatsInfonew.setUserCode(info.getUserCode()); // 设置统计表用户编号
                userStatsInfonew.setValiFlag("1");// 设置默认有效标识
                userStatsInfonew.setCreateTime(new Date());
                userstatsInfoMapper.insert(userStatsInfonew);
            }
            Integer currentOnlineTime = userStatsInfo.getInlineTime();
            Integer nowCurrentOnlineTime = currentOnlineTime + onlineTimeAdd;
            userStatsInfo.setInlineTime(nowCurrentOnlineTime);
            userstatsInfoMapper.updateById(userStatsInfo);

        }
        else{ // 统计表中数据为空、数据不是同一天的 -- 直接添加新数据
            // 初始化新增的用户信息统计分析表
            UserStatsInfo userStatsInfonew = new UserStatsInfo();
            String Idkey = SnowFlakeUtil.getId(); // 获取主键
            userStatsInfonew.setId(Idkey); // 设置唯一标识
            userStatsInfonew.setUserstatsCode(Idkey); // 设置主键
            userStatsInfonew.setInlineTime(onlineTimeAdd ); // 设置当前用户在线实际时长
            userStatsInfonew.setUserCode(info.getUserCode()); // 设置统计表用户编号
            userStatsInfonew.setValiFlag("1");// 设置默认有效标识
            userStatsInfonew.setCreateTime(new Date());
            userstatsInfoMapper.insert(userStatsInfonew);
        }
    }

}
